/* 
 * Copyright (c) 2018, S.F. Express Inc. All rights reserved.
 */
package com.sf.proxy.util;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 描述：
 * 
 * <pre>
 * HISTORY
 * ****************************************************************************
 *  ID   DATE           PERSON          REASON
 *  1    2018年8月13日      01380084         Create
 * ****************************************************************************
 * </pre>
 * 
 * @author 01380084
 * @since 1.0
 */
public abstract class AsycUtils {

	private static int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors();
	private static int MAX_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2;

	private static ThreadPoolExecutor EXECUTOR_SERVICE = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, 60L,
			TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(40000*MAX_POOL_SIZE), new CustomThreadfactory(), new CustomRejectPolicy());

	private AsycUtils() {

	}

	public static void execute(Runnable task) {
		EXECUTOR_SERVICE.execute(task);
	}
	
	public static <T> Future<T> execute(Callable<T> task) {
		return EXECUTOR_SERVICE.submit(task);
	}

	/**
	 * custom thread factory for the custom thread name "asyc-utils-thread-pool"
	 * 描述：
	 *
	 * <pre>HISTORY
	 * ****************************************************************************
	 *  ID   DATE           PERSON          REASON
	 *  1    2018年8月13日      01380084         Create
	 * ****************************************************************************
	 * </pre>
	 * @author 01380084
	 * @since 1.0
	 */
	private static class CustomThreadfactory implements ThreadFactory {

		private static SecurityManager SM = System.getSecurityManager();
		private static final ThreadGroup GROUP = (SM != null) ? SM.getThreadGroup()
				: Thread.currentThread().getThreadGroup();
		private final AtomicInteger THREAD_NUMBER = new AtomicInteger(1);
		private static final String NAME_PREFIX = "asyc-utils-thread-pool-" + "-thread-";

		@Override
		public Thread newThread(Runnable r) {
			Thread t = new Thread(GROUP, r, NAME_PREFIX + THREAD_NUMBER.getAndIncrement(), 0);
			if (t.isDaemon())
				t.setDaemon(false);
			if (t.getPriority() != Thread.NORM_PRIORITY)
				t.setPriority(Thread.NORM_PRIORITY);
			return t;
		}

	}

	/**
	 * For the custom reject policy if the thread pool is almost over
	 * 描述：
	 *
	 * <pre>HISTORY
	 * ****************************************************************************
	 *  ID   DATE           PERSON          REASON
	 *  1    2018年8月13日      01380084         Create
	 * ****************************************************************************
	 * </pre>
	 * @author 01380084
	 * @since 1.0
	 */
	private static class CustomRejectPolicy implements RejectedExecutionHandler {

		@Override
		public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
			 throw new RejectedExecutionException("异步工具类task满了，抛出异常拒绝执行任务！ " + r.toString() +
                     " rejected from " +
                     executor.toString());
		}

	}

}
